package com.summer.user.controller;

import java.io.Serializable;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.springframework.context.annotation.Scope;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.summer.core.annotations.Logger;
import com.summer.core.annotations.ScopeType;
import com.summer.core.controller.EntityHome;
import com.summer.core.controller.LoginUserInfo;
import com.summer.core.service.BaseService;
import com.summer.core.util.FacesUtil;
import com.summer.core.util.HashCrypt;
import com.summer.core.util.IdGenerator;
import com.summer.core.util.StringManager;
import com.summer.dingding.model.DingDingUser;
import com.summer.dingding.service.DingDingService;
import com.summer.dingding.util.DingDingConstants;
import com.summer.user.UserConstants;
import com.summer.user.exception.ConfigNotFoundException;
import com.summer.user.exception.UserNotFoundException;
import com.summer.user.model.User;
import com.summer.user.model.UserLoginLog;
import com.summer.user.service.UserService;
import com.summer.user.service.impl.UserBO;



@Component
@Scope(ScopeType.VIEW)
public class UserHome extends EntityHome<User> implements Serializable{

	private static final long serialVersionUID= 1l;
	
	@Resource
	HibernateTemplate ht;
	
	@Resource
	UserBO userBO;
	
	@Resource
	private UserService userService;
	
	@Logger
	static Log log;
	private static StringManager sm = StringManager
			.getManager(UserConstants.Package);

	
	@Resource
	private LoginUserInfo loginUser;
	
	private String oldPassword;
	
	@Resource
	UserDetailsService userDetailsService;
	
	@Resource
	SessionRegistry sessionRegistry;
	
	@Resource
	BaseService<Object> baseService;
	
	@Resource
	LoginUserInfo loginUserInfo;
	
	@Resource
	DingDingService dingDingService;
	/**
	 * 后台保存用户
	 */
	@Override
	@Transactional(readOnly = false)
	public String save() {
		// FIXME:放在service中
		if (StringUtils.isEmpty(getInstance().getId())) {
			getInstance().setId(getInstance().getUsername());
			getInstance().setPassword(HashCrypt.getDigestHash("111111"));
			FacesUtil.addInfoMessage("用户创建成功，初始密码为111111，请及时通知用户修改密码！");
			getInstance().setRegisterTime(new Date());
		}

		setUpdateView(FacesUtil.redirect("/admin/user/userList"));
		return super.save();
	}
	
	/**
	 * 管理员修改用户，修改普通信息和邮箱、手机，不可修改密码等
	 * 
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public String modifyByAdmin() {
		
		
		if (!StringUtils.isEmpty(getInstance().getEmail())) {
			User user = userBO.getUserByEmail(getInstance().getEmail());
			if (user != null && !user.getId().equals(getInstance().getId())) {
				FacesUtil.addErrorMessage("该邮箱已存在！");
				return null;
			}
		}
		if (!StringUtils.isEmpty(getInstance().getMobileNumber())) {
			User user = userBO.getUserByMobileNumber(getInstance()
					.getMobileNumber());
			if (user != null && !user.getId().equals(getInstance().getId())) {
				FacesUtil.addErrorMessage("该手机号已存在！");
				return null;
			}
		}
		baseService.merge(getInstance());
		FacesUtil.addInfoMessage("用户信息修改成功！");
		return FacesUtil.redirect("/admin/user/userList");
	}
	
	/**
	 * 修改密码
	 * 
	 * @return
	 */
	public String modifyPassword() {
		String userId = loginUser.getLoginUserId();
		try {
			if (!userService.verifyOldPassword(userId, oldPassword)) {
				FacesUtil.addErrorMessage("输入旧密码错误，请重新输入！");
				return null;
			}
			if (HashCrypt.getDigestHash(getInstance().getPassword()).equals(
					getInstance().getCashPassword())) {
				FacesUtil.addErrorMessage("登录密码不能与交易密码相同");
				return null;
			}
			userService.modifyPassword(loginUser.getLoginUserId(),
					getInstance().getPassword());
			FacesUtil.addInfoMessage("密码修改成功！");
			return "pretty:userCenter";
		} catch (UserNotFoundException e) {
			FacesUtil.addErrorMessage("用户未登录！");
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 禁止用户
	 * 
	 * @return
	 */
	public String forbid(String userId) {
		// if (log.isInfoEnabled()) {
		// log.info(sm.getString("log.info.forbidUser",
		// userId, new Date(), userId));
		// }
		try {
			userService.changeUserStatus(userId,
					UserConstants.UserStatus.DISABLE);
		} catch (ConfigNotFoundException e) {
		} catch (UserNotFoundException e) {
			FacesUtil.addErrorMessage("该用户不存在");
		}
		return getSaveView();
	}
	
	public void loginByDingding() {
		
	}
	
	public void registerAfterLogin(String username) {
		UserDetails userDetails = userDetailsService
				.loadUserByUsername(username);
		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
				username, userDetails.getPassword(),
				userDetails.getAuthorities());
		SecurityContextHolder.getContext().setAuthentication(token);
		HttpSession session = FacesUtil.getHttpSession();
		session.setAttribute(
				HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
				SecurityContextHolder.getContext());
		sessionRegistry.registerNewSession(session.getId(), userDetails);

	}
	
	public void toALiDingDing(String from) {
		String url = "";
		if(from == null || from.equals("")) {
			FacesUtil.addErrorMessage("操作异常！");
			return;
		}
		if(from.equals("bind")) {
			url = URLEncoder.encode(DingDingConstants.Config.CodeLogin.REDIRECT_URL_BIND);
		} else if(from.equals("login")) {
			url = URLEncoder.encode(DingDingConstants.Config.CodeLogin.REDIRECT_URL_LOGIN);
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("https://oapi.dingtalk.com/connect/qrconnect?appid=").append(DingDingConstants.Config.CodeLogin.APPID).append("&")
				.append("response_type=code&scope=snsapi_login&state=").append(System.currentTimeMillis())
				.append("&redirect_uri=").append(url);
		FacesUtil.sendRedirect(stringBuilder.toString());
	}
	
	public String testMessage() {
		FacesUtil.addErrorMessage("呵呵呵呵呵");
		return FacesUtil.redirect("/admin/index.htm" + "&faces-redirect=true");
	}
	public void testMessage1() {
		FacesUtil.addErrorMessage("呵呵呵呵呵");
//		return FacesUtil.redirect("/admin/index.htm" + "&faces-redirect=true");
	}
	
	@SuppressWarnings("unchecked")
	public String loginWeb() {
		HttpServletRequest request = FacesUtil.getHttpServletRequest();
		String errorMsg = "操作异常！";
		if(request == null) {
			errorMsg = "未知请求！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		Map<String ,String[]> map = request.getParameterMap();
		if(map == null || map.size() == 0) {
			errorMsg = "请求参数为空！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		JSONObject json = dingDingService.goDingLogin(map.get("code")[0]);
		if(json == null || json.size() == 0) {
			errorMsg = "请求参数为空！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		System.out.println(json);
		String userid = json.getString("userid");
		String unionid = json.getString("unionid");
		if(userid == null || unionid == null || userid.equals("") || unionid.equals("")) {
			errorMsg = "用户信息有误！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		List<DingDingUser> dUserList = ht.find("from DingDingUser duser where duser.userid = ? and duser.unionid = ? and duser.bindStatus = ?", userid, unionid, "1");
		if(dUserList == null || dUserList.size() == 0) {
			FacesUtil.addErrorMessage("没有账号绑定到此钉钉账号");
//			return null;
		} else {
			DingDingUser dingDingUser = dUserList.get(0);
			User user = ht.get(User.class, dingDingUser.getUser().getId());
			UserDetails userDetails = userDetailsService
					.loadUserByUsername(user.getId());
			UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
					user.getId(), userDetails.getPassword(),
					userDetails.getAuthorities());
			SecurityContextHolder.getContext().setAuthentication(token);
			HttpSession session = FacesUtil.getHttpSession();
			session.setAttribute(
					HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
					SecurityContextHolder.getContext());
			sessionRegistry.registerNewSession(session.getId(), userDetails);
			addUserLoginLog(user, request, "dingding", UserConstants.UserLoginLog.SUCCESS);
			FacesUtil.addInfoMessage("欢迎回来！");
		}
		
		FacesUtil.addMessagesOutOfJSFLifecycle(FacesUtil.getCurrentInstance());
		FacesUtil.getCurrentInstance().responseComplete();
		return FacesUtil.redirect("/admin/index.htm" + "&faces-redirect=true");
	}
	
	private void addUserLoginLog(User user, HttpServletRequest request, String from, 
			String isSuccess) {
		// 记录user登录信息
		UserLoginLog ull = new UserLoginLog();
		ull.setId(IdGenerator.randomUUID());
		ull.setIsSuccess(isSuccess);
		ull.setLoginIp(FacesUtil.getRequestIp(request));
		ull.setLoginTime(new Timestamp(System.currentTimeMillis()));
		ull.setUsername(user.getUsername());
		ull.setLoginInfo(from);
		
		baseService.save(ull);
	}
	
	@SuppressWarnings("unchecked")
	public String bindWeb() {
		
		HttpServletRequest request = FacesUtil.getHttpServletRequest();
		String errorMsg = "操作异常！";
		if(request == null) {
			errorMsg = "未知请求！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		Map<String ,String[]> map = request.getParameterMap();
		if(map == null || map.size() == 0) {
			errorMsg = "请求参数为空！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		JSONObject json = dingDingService.goDingLogin(map.get("code")[0]);
		if(json == null || json.size() == 0) {
			errorMsg = "请求参数为空！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		System.out.println(json);
		String userid = json.getString("userid");
		String unionid = json.getString("unionid");
		if(userid == null || unionid == null || userid.equals("") || unionid.equals("")) {
			errorMsg = "用户信息有误！";
			FacesUtil.addErrorMessage(errorMsg);
			return null;
		}
		List<DingDingUser> dUserList = ht.find("from DingDingUser duser where duser.userid = ? and duser.unionid = ?", userid, unionid);
		if(dUserList == null || dUserList.size() == 0) {
			DingDingUser duser = JSONObject.parseObject(json.toJSONString(), DingDingUser.class);
			User user = ht.get(User.class, loginUserInfo.getLoginUserId());
			duser.setId(duser.getUserid());
			duser.setUser(user);
			duser.setBindStatus("1");
			baseService.save(duser);
		} else {
			DingDingUser duser = dUserList.get(0);
			if(duser.getBindStatus() == null || !duser.getBindStatus().equals("1")) {
				duser.setBindStatus("1");
				baseService.merge(duser);
			}
		}
		
		FacesUtil.addInfoMessage("绑定钉钉成功！");
		FacesUtil.addMessagesOutOfJSFLifecycle(FacesUtil.getCurrentInstance());
		return FacesUtil.redirect("/admin/index.htm" + "&faces-redirect=true");
	}
	
	/**
	 * 解禁用户
	 * 
	 * @return
	 */
	public String release(String userId) {
		if (log.isInfoEnabled()) {
			log.info(sm.getString("log.info.releaseUser", FacesUtil
					.getExpressionValue("#{loginUserInfo.loginUserId}"),
					new Date(), userId));
		}
		try {
			userService.changeUserStatus(userId,
					UserConstants.UserStatus.ENABLE);
			// FIXME:下面异常不合理
		} catch (ConfigNotFoundException e) {
		} catch (UserNotFoundException e) {
			FacesUtil.addErrorMessage("该用户不存在");
		}
		return getSaveView();
	}
	
	public String unBindDingDing(String userId, boolean isAdmin) {
		try {
			userService.changeBindDingDingStatus(userId, "0");
			// FIXME:下面异常不合理
		} catch (ConfigNotFoundException e) {
		} catch (UserNotFoundException e) {
			FacesUtil.addErrorMessage("该用户不存在");
		}
		if(isAdmin) {
			
			return getSaveView();
		} else {
			FacesUtil.addInfoMessage("解绑成功！");
			return FacesUtil.redirect("/admin/index.htm" + "&faces-redirect=true");
		}
	}

	public String getOldPassword() {
		return oldPassword;
	}

	public void setOldPassword(String oldPassword) {
		this.oldPassword = oldPassword;
	}
	
	
}
